package server

import (
//	"github.com/cz-it/gonnectd/proto"
	"github.com/cz-it/gonnectd/utils/log"

	"net"
	"os"
	"time"
)

const (
	// some magic define
	RETRY_TIME_MAX  = 1 * time.Second
	RETRY_TIME_MUL  = 2
	RETRY_TIME_BASE = 5 * time.Millisecond
	ALIVE_TIME      = 3 * time.Minute
)

type Server struct {
	Addr      *net.TCPAddr
	AliveTime time.Duration

}

func New() *Server {
	s := new(Server)
	return s
}

func (svr *Server) Init() {
	svr.AliveTime = ALIVE_TIME
}

func (svr *Server) SetAddr(ip string,port int) {
	svr.Addr = &net.TCPAddr{net.ParseIP(ip),port,""}
}

func (svr *Server) Run() {
	log.Info("run")
	ln, err := net.ListenTCP("tcp4", svr.Addr)

	if err != nil {
		log.Error(err.Error())
		panic(err)
	}

	var tempDelay time.Duration // how long to sleep on accept failure
	for {
		conn, err := ln.AcceptTCP()
		if err != nil {
			if ne, ok := err.(net.Error); ok && ne.Temporary() {
				if tempDelay == 0 {
					tempDelay = RETRY_TIME_BASE * time.Millisecond
				} else {
					tempDelay *= RETRY_TIME_MUL
				}
				if tempDelay > RETRY_TIME_MAX {
					tempDelay = RETRY_TIME_MAX
				}
				log.Error("http: Accept error: %v; retrying in %v", err, tempDelay)
				time.Sleep(tempDelay)
				continue
			}
			log.Error(err.Error())
			os.Exit(-1)
		}

		// choose keepalived connection
		conn.SetKeepAlive(true)
		conn.SetKeepAlivePeriod(svr.AliveTime)

		c := NewConn(conn, svr)
		go c.Serve()
	}
}
